package tt.dz.service.imp.middleware.notify.app;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Component;
import tt.dz.dao.base.BasisDao;
import tt.dz.dao.ext.charger.OmsChargerChargeBillRecordDao;
import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerChargeBillRecord;
import tt.dz.entity.exception.BizException;
import tt.dz.tcp.rpc.as.SystemAppServerRpcClient;
import tt.dz.tcp.rpc.as.client.constant.AppServerConstant;
import tt.dz.tcp.rpc.as.client.entity.AppChargeNotifyParam;
import tt.dz.tcp.rpc.as.client.entity.AppExceptionNotifyParam;
import tt.dz.util.StringUtil;

/**
 * 通知AppServer
 *
 * @author peizhide
 */
@Component
public class NotifyAppServer implements ApplicationContextAware
{

	private static Log log = LogFactory.getLog(NotifyAppServer.class);

	private static ApplicationContext applicationContext;

	//	@Autowired
	//	private static OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	//	@Autowired
	//	private static OmsChargerDao omsChargerDao;
	//	@Autowired
	//	private static SystemAppServerRpcClient systemAppServerRpcClient;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
	{
		log.debug("Init application context");
		NotifyAppServer.applicationContext = applicationContext;
	}

	/**
	 * 开始充电返回成功
	 *
	 * @param msg_charge_jrnl 开始充电下发流水号
	 */
	public static void startChargeReturn(String msg_charge_jrnl)
	{
		log.info("Send to message startChargeReturn(NotifyAppServer) start!");
		AppChargeNotifyParam obj = new AppChargeNotifyParam();
		JsonCommon<String> json = new JsonCommon<String>();
		obj.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_CHARGE); // 开始充电

		OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao = applicationContext.getBean(OmsChargerChargeBillRecordDao.class);

		OmsChargerChargeBillRecord omsChargerChargeBillRecord = new OmsChargerChargeBillRecord();
		OmsChargerChargeBillRecord omsChargerChargeBillRecord_query = new OmsChargerChargeBillRecord();
		omsChargerChargeBillRecord_query.setMsg_charge_jrnl(msg_charge_jrnl);
		omsChargerChargeBillRecord = omsChargerChargeBillRecordDao.findOneExample(omsChargerChargeBillRecord_query, null, null);
		if (StringUtil.objectIsNull(omsChargerChargeBillRecord))
		{
			log.error("Send to message stopChargeReturn(NotifyAppServer), result:fail, reason:omsChargerChargeBillRecord is null!");
			return;
		}

		if (StringUtil.isEmpty(omsChargerChargeBillRecord.getBespeak_jrnl()))
		{
			obj.setChargeType("0"); // 非预约充电
		}
		else
		{
			obj.setChargeType("1"); // 预约充电
		}

		OmsChargerDao omsChargerDao = applicationContext.getBean(OmsChargerDao.class);

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(omsChargerChargeBillRecord.getCharger_id());
		charger_query.setPort_no(omsChargerChargeBillRecord.getPort_no());
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		if (StringUtil.objectIsNull(charger))
		{
			log.error("Send to message stopChargeReturn(NotifyAppServer), result:fail, reason:charger is null!");
			return;
		}

		obj.setStationName(charger.getStation_name());
		obj.setSerialNo(charger.getSerial_no());
		obj.setPlugNo(String.valueOf(omsChargerChargeBillRecord.getPort_no()));
		obj.setChargerId(omsChargerChargeBillRecord.getCharger_id());
		obj.setUserCard(omsChargerChargeBillRecord.getUser_pay_card());
		obj.setChargeSn(omsChargerChargeBillRecord.getCharge_jrnl());
		obj.setStartTime(omsChargerChargeBillRecord.getStart_time().toString());
		json.setPojo(omsChargerChargeBillRecord.toString());

		SystemAppServerRpcClient systemAppServerRpcClient = applicationContext.getBean(SystemAppServerRpcClient.class);

		json = systemAppServerRpcClient.chargeNotify(obj);

		if (json.getCode().equals("200"))
		{
			log.debug("Send to message startChargeReturn(NotifyAppServer), result:success!");
		}
		else
		{
			log.error("Send to message startChargeReturn(NotifyAppServer), result:fail, reason:systemAppServerRpcClient chargeNotify fail!");
		}
		log.info("Send to message startChargeReturn(NotifyAppServer) end!");
	}

	/**
	 * 停止充电返回成功
	 *
	 * @param msg_charge_jrnl 开始充电下发流水号
	 */
	public static void stopChargeReturn(String msg_charge_jrnl)
	{
		log.info("Send to message stopChargeReturn(NotifyAppServer) start!");
		JsonCommon<String> json = new JsonCommon<String>();
		AppChargeNotifyParam obj = new AppChargeNotifyParam();
		obj.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_END_CHARGE); // 结束充电

		OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao = applicationContext.getBean(OmsChargerChargeBillRecordDao.class);

		OmsChargerChargeBillRecord omsChargerChargeBillRecord = new OmsChargerChargeBillRecord();
		OmsChargerChargeBillRecord omsChargerChargeBillRecord_query = new OmsChargerChargeBillRecord();
		omsChargerChargeBillRecord_query.setMsg_charge_jrnl(msg_charge_jrnl);
		omsChargerChargeBillRecord = omsChargerChargeBillRecordDao.findOneExample(omsChargerChargeBillRecord_query, null, null);
		if (StringUtil.objectIsNull(omsChargerChargeBillRecord))
		{
			log.error("Send to message stopChargeReturn(NotifyAppServer), result:fail, reason:omsChargerChargeBillRecord is null!");
			return;
		}

		OmsChargerDao omsChargerDao = applicationContext.getBean(OmsChargerDao.class);

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(omsChargerChargeBillRecord.getCharger_id());
		charger_query.setPort_no(omsChargerChargeBillRecord.getPort_no());
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		if (StringUtil.objectIsNull(charger))
		{
			log.error("Send to message stopChargeReturn(NotifyAppServer), result:fail, reason:charger is null!");
			return;
		}

		if (omsChargerChargeBillRecord.getBespeak_jrnl() == null || "".equals(omsChargerChargeBillRecord.getBespeak_jrnl())) {
			obj.setChargeType("0"); // 非预约充电
		} else {
			obj.setChargeType("1"); // 预约充电
		}

		obj.setStationName(charger.getStation_name());
		obj.setSerialNo(charger.getSerial_no());
		obj.setPlugNo(String.valueOf(charger.getPort_no()));
		obj.setChargerId(omsChargerChargeBillRecord.getCharger_id());
		obj.setUserCard(omsChargerChargeBillRecord.getUser_pay_card());
		obj.setChargeSn(omsChargerChargeBillRecord.getCharge_jrnl());
		obj.setStartTime(omsChargerChargeBillRecord.getStart_time().toString());
		json.setPojo(omsChargerChargeBillRecord.toString());

		SystemAppServerRpcClient systemAppServerRpcClient = applicationContext.getBean(SystemAppServerRpcClient.class);

		json = systemAppServerRpcClient.chargeNotify(obj);
		if (json.getCode().equals("200"))
		{
			log.debug("Send to message stopChargeReturn(NotifyAppServer), result:success!");
		}
		else
		{
			log.error("Send to message stopChargeReturn(NotifyAppServer), result:fail, reason:systemAppServerRpcClient chargeNotify fail!");
		}
		log.info("Send to message stopChargeReturn(NotifyAppServer) end!");
	}

	/**
	 * 异常通知
	 *
	 * @param action       动作
	 * @param serialNumber 流水号
	 * @param chargerId    桩号
	 * @param responseCode 错误码
	 * @throws BizException
	 */
	@SuppressWarnings("rawtypes")
	public static void exceptionNotify(String action, String serialNumber, String chargerId, String responseCode) throws BizException
	{
		log.info("Send to message exceptionNotify(NotifyAppServer) start!");
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT c.charger_id, s.station_name, c.serial_no, tt.charge_jrnl, tt.user_pay_card as tt_user_pay_card, tt.start_time as tt_start_time, ");
		sql.append("bb.bespeak_jrnl, bb.user_pay_card as bb_user_pay_card, bb.start_time as bb_start_time ");
		sql.append("FROM oms_charger c ");
		sql.append("LEFT JOIN oms_station s ON s.station_id = c.station_id ");
		sql.append("LEFT JOIN ( ");
		sql.append("SELECT t.charge_jrnl, t.charger_id, t.start_time, t.user_pay_card ");
		sql.append("FROM oms_charger_charge_bill_record t ");
		sql.append("WHERE t.msg_charge_jrnl = '" + serialNumber + "' ");
		sql.append(") tt ON tt.charger_id = c.charger_id ");
		sql.append("LEFT JOIN ( ");
		sql.append("SELECT b.bespeak_jrnl, b.charger_id, b.start_time, b.user_pay_card ");
		sql.append("FROM oms_charger_bespeak_bill_record b ");
		sql.append("WHERE b.oms_msg_bespeak_jrnl = '" + serialNumber + "' ");
		sql.append(") bb ON bb.charger_id = c.charger_id ");
		sql.append("WHERE c.charger_id = '" + chargerId + "'");

		OmsChargerChargeBillRecordDao dao = applicationContext.getBean(OmsChargerChargeBillRecordDao.class);

		final AppExceptionNotifyParam obj = new AppExceptionNotifyParam();
		obj.setAction(action);
		obj.setResponseCode(responseCode); // 错误码

		dao.getJdbcTemplate().query(sql.toString(), new ResultSetExtractor<Object>()
		{
			@Override
			public Object extractData(ResultSet rs) throws SQLException, DataAccessException
			{
				if (rs.next())
				{
					obj.setChargerId(rs.getString("charger_id"));
					obj.setStationName(rs.getString("station_name"));
					obj.setSerialNo(rs.getString("serial_no"));
					obj.setUserCard(rs.getString("tt_user_pay_card") == null ? rs.getString("bb_user_pay_card") : rs.getString("tt_user_pay_card"));
					obj.setReservationSn(rs.getString("bespeak_jrnl"));
					obj.setChargeSn(rs.getString("charge_jrnl"));
					obj.setStartTime(rs.getString("tt_start_time") == null ? rs.getString("bb_start_time") : rs.getString("tt_start_time"));
				}
				return null;
			}
		});

		if (StringUtils.isNotEmpty(obj.getChargerId()))
		{

			SystemAppServerRpcClient systemAppServerRpcClient = applicationContext.getBean(SystemAppServerRpcClient.class);

			JsonCommon json = systemAppServerRpcClient.exceptionNotify(obj);
			log.info("Send to message exceptionNotify(NotifyAppServer) end!");
			if (!json.getCode().equals(AppServerConstant.RELULT_INFO_APP_SERVIER_NOTIFY_SUCCESS_CODE))
				throw new BizException(json.getCode() + ", " + json.getMsg());
		}
	}
}
